package cn.z2huo.knowledge.designpattern.proxy.dynamic.example;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * <p>
 *
 * @author z2huo
 */
class MyInvocationHandler implements InvocationHandler {

    private final MyService myService;

    public MyInvocationHandler() {
        this.myService = new MyServiceImpl();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理对象：" + proxy.getClass().getName());
        System.out.println(method.getName() + " before");
        Object object = method.invoke(myService, args);
        System.out.println(method.getName() + " after");
        return object;
    }

    public static void main(String[] args) throws ClassNotFoundException, IOException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
//        MyService proxy = (MyService) Proxy.newProxyInstance(MyService.class.getClassLoader(),
//                new Class[]{MyService.class}, myInvocationHandler);
        MyService proxy = (MyService) Proxy.newProxyInstance(MyInvocationHandler.class.getClassLoader(),
                new Class[]{MyService.class}, myInvocationHandler);

        // todo 这里的 getProxyClass 方法的第一个参数是一个类加载器，到底是使用哪个类的类加载器呢？
//        Class<? > proxyClazz = Proxy.getProxyClass(MyService.class.getClassLoader(), MyService.class);
//        Class<? > proxyClazz = Proxy.getProxyClass(MyInvocationHandler.class.getClassLoader(), MyService.class);
//        Constructor<? > ctor = proxyClazz.getConstructor(InvocationHandler.class);
//        InvocationHandler myInvocationHandler = new MyInvocationHandler();
//        MyService proxy = (MyService) ctor.newInstance(myInvocationHandler);

        proxy.request();
        System.out.println();
        proxy.response();

//        File file = new File("output/$Proxy0.class");
//        if (!file.exists()) {
//            file.createNewFile();
//        }
//
//        // 创建一个继承自 Object 的类，并重写 toString() 方法
//        DynamicType.Unloaded<?> unloaded = new ByteBuddy()
//                .subclass(proxyClazz)
//                .name("cn.z2huo.knowledge.designpattern.proxy.dynamic.example")  // 指定类名和包路径
//                .make();
//
//        unloaded.saveIn(file);
//
//        System.out.println();
//        System.out.println(Proxy.isProxyClass(proxy.getClass()));
//        System.out.println(Proxy.isProxyClass(myInvocationHandler.getClass()));
//
//        System.out.println();
//        InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);
//        System.out.println(invocationHandler);
    }

    @Override
    public String toString() {
        return "this is a InvocationHandler";
    }
}